package com.woniuxy.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import com.woniuxy.order.dto.OrderApplicationDto;
import com.woniuxy.order.dto.OrderApprovalDto;
import com.woniuxy.order.dto.OrderProcessDto;
import com.woniuxy.order.entity.OrderApplication;
import com.woniuxy.order.entity.OrderApprovalRecord;
import com.woniuxy.order.entity.OrderStatusLog;
import com.woniuxy.order.mapper.OrderApplicationMapper;
import com.woniuxy.order.mapper.OrderApprovalRecordMapper;
import com.woniuxy.order.mapper.OrderStatusLogMapper;
import com.woniuxy.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 */
@Slf4j
@Service
@Transactional
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    private OrderApplicationMapper orderApplicationMapper;
    
    @Autowired
    private OrderApprovalRecordMapper orderApprovalRecordMapper;
    
    @Autowired
    private OrderStatusLogMapper orderStatusLogMapper;
    
    @Autowired
    private com.woniuxy.order.client.FlowableClient flowableClient;
    
    @Override
    public OrderApplication createOrderApplication(OrderApplicationDto orderApplicationDto, String currentUser) {
        OrderApplication orderApplication = new OrderApplication();
        BeanUtils.copyProperties(orderApplicationDto, orderApplication);
        
        // 生成订单编号
        orderApplication.setOrderNo(generateOrderNo());
        orderApplication.setApplicationStatus("PENDING");
        orderApplication.setCreateBy(currentUser);
        orderApplication.setUpdateBy(currentUser);
        
        // 设置办事处业务ID默认值（如果未提供）
        if (orderApplication.getOfficeBusinessId() == null) {
            orderApplication.setOfficeBusinessId(1L); // 默认办事处ID
        }
        
        // 设置办事处业务名称默认值（如果未提供）
        if (orderApplication.getOfficeBusinessName() == null) {
            orderApplication.setOfficeBusinessName("默认办事处"); // 默认办事处名称
        }
        
        // 计算总金额
        if (orderApplication.getUnitPrice() != null && orderApplication.getQuantity() != null) {
            orderApplication.setTotalAmount(orderApplication.getUnitPrice().multiply(new java.math.BigDecimal(orderApplication.getQuantity())));
        }
        
        orderApplicationMapper.insert(orderApplication);
        
        // 记录状态变更日志
        saveOrderStatusLog(orderApplication.getId(), orderApplication.getOrderNo(), null, 
            orderApplication.getApplicationStatus(), "创建订单申请", currentUser);
        
        log.info("创建订单申请成功，订单ID：{}，订单编号：{}", orderApplication.getId(), orderApplication.getOrderNo());
        return orderApplication;
    }
    
    @Override
    public org.springframework.data.domain.Page<OrderApplication> getOrderApplications(org.springframework.data.domain.Pageable pageable, String customerName, String applicationStatus, String currentUser) {
        // 将 Spring Data Pageable 转换为 MyBatis-Plus Page
        Page<OrderApplication> pageParam = new Page<>(pageable.getPageNumber() + 1, pageable.getPageSize());
        QueryWrapper<OrderApplication> queryWrapper = new QueryWrapper<>();
        
        if (customerName != null && !customerName.trim().isEmpty()) {
            queryWrapper.like("customer_name", customerName);
        }
        if (applicationStatus != null && !applicationStatus.trim().isEmpty()) {
            queryWrapper.eq("application_status", applicationStatus);
        }
        
        queryWrapper.orderByDesc("create_time");
        
        Page<OrderApplication> mybatisPage = orderApplicationMapper.selectPage(pageParam, queryWrapper);
        
        // 转换为 Spring Data Page
        return new PageImpl<>(mybatisPage.getRecords(), pageable, mybatisPage.getTotal());
    }
    
    @Override
    public OrderApplication getOrderApplicationById(Long orderId) {
        return orderApplicationMapper.selectById(orderId);
    }
    
    @Override
    public OrderApplication getOrderApplicationByOrderNo(String orderNo) {
        QueryWrapper<OrderApplication> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        return orderApplicationMapper.selectOne(queryWrapper);
    }
    
    @Override
    public OrderApplication updateOrderApplication(Long orderId, OrderApplicationDto orderApplicationDto, String currentUser) {
        OrderApplication existingOrder = orderApplicationMapper.selectById(orderId);
        if (existingOrder == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!"PENDING".equals(existingOrder.getApplicationStatus())) {
            throw new RuntimeException("只有待审批状态的订单才能修改");
        }
        
        String oldStatus = existingOrder.getApplicationStatus();
        
        // 更新订单信息
        BeanUtils.copyProperties(orderApplicationDto, existingOrder, "id", "orderNo", "createTime", "createBy");
        existingOrder.setUpdateBy(currentUser);
        
        // 重新计算总金额
        if (existingOrder.getUnitPrice() != null && existingOrder.getQuantity() != null) {
            existingOrder.setTotalAmount(existingOrder.getUnitPrice().multiply(new java.math.BigDecimal(existingOrder.getQuantity())));
        }
        
        orderApplicationMapper.updateById(existingOrder);
        
        // 记录状态变更日志
        saveOrderStatusLog(existingOrder.getId(), existingOrder.getOrderNo(), oldStatus, 
            existingOrder.getApplicationStatus(), "修改订单申请", currentUser);
        
        log.info("更新订单申请成功，订单ID：{}，订单编号：{}", existingOrder.getId(), existingOrder.getOrderNo());
        return existingOrder;
    }
    
    @Override
    public void deleteOrderApplication(Long orderId, String currentUser) {
        OrderApplication order = orderApplicationMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!"PENDING".equals(order.getApplicationStatus())) {
            throw new RuntimeException("只有待审批状态的订单才能删除");
        }
        
        orderApplicationMapper.deleteById(orderId);
        
        // 记录状态变更日志
        saveOrderStatusLog(order.getId(), order.getOrderNo(), order.getApplicationStatus(), 
            "DELETED", "删除订单申请", currentUser);
        
        log.info("删除订单申请成功，订单ID：{}，订单编号：{}", order.getId(), order.getOrderNo());
    }
    
    @Override
    public String submitOrderApplication(Long orderId, String currentUser) {
        OrderApplication order = orderApplicationMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!"PENDING".equals(order.getApplicationStatus())) {
            throw new RuntimeException("只有待审批状态的订单才能提交审批");
        }
        
        // 准备流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("orderId", String.valueOf(order.getId()));
        variables.put("orderNo", order.getOrderNo());
        variables.put("orderAmount", order.getTotalAmount());
        variables.put("customerName", order.getCustomerName());
        variables.put("applicant", currentUser);
        // 配置回调URL（供 flowable-server 回调，通过网关）
        variables.put("callbackUrl", "http://localhost:9999/order-management/api/orders/callback");
        
        // 添加 BPMN 文件中需要的流程变量（使用用户名作为任务分配人）
        // 办事处商务使用当前登录用户
        variables.put("officeBusinessId", currentUser);
        variables.put("officeBusinessName", order.getOfficeBusinessName());
        variables.put("regionalManagerId", "regional_manager"); // 地区经理用户名
        variables.put("regionalDirectorId", "regional_director"); // 大区经理用户名
        variables.put("marketingId", "marketing_manager"); // 市场经理用户名
        variables.put("logisticsDirectorId", "logistics_director"); // 物流总监用户名
        variables.put("salesDirectorId", "sales_director"); // 销售总监用户名
        variables.put("companyBusinessId", "company_business"); // 公司商务用户名
        
        try {
            // 调用 Flowable 服务启动流程
            String processInstanceId = flowableClient.startProcess(
                "OrderApprovalProcess",  // 流程定义Key（首字母大写）
                String.valueOf(order.getId()),  // 业务Key
                variables
            );
            
            // 自动完成第一个任务（办事处商务填写订单），因为订单已经创建好了
            flowableClient.completeFirstTask(currentUser, processInstanceId);
            
            // 更新订单状态
            order.setProcessInstanceId(processInstanceId);
            order.setCurrentStep("地区经理审批");
            order.setApplicationStatus("APPROVING");
            order.setUpdateBy(currentUser);
            
            orderApplicationMapper.updateById(order);
            
            // 记录状态变更日志
            saveOrderStatusLog(order.getId(), order.getOrderNo(), "PENDING", 
                "APPROVING", "提交审批流程", currentUser);
            
            log.info("提交订单审批成功，订单ID：{}，订单编号：{}，流程实例ID：{}", 
                order.getId(), order.getOrderNo(), processInstanceId);
            return processInstanceId;
            
        } catch (Exception e) {
            log.error("启动工作流失败", e);
            throw new RuntimeException("提交审批失败: " + e.getMessage());
        }
    }
    
    @Override
    public void cancelOrderApplication(Long orderId, String reason, String currentUser) {
        OrderApplication order = orderApplicationMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if ("APPROVED".equals(order.getApplicationStatus()) || "REJECTED".equals(order.getApplicationStatus())) {
            throw new RuntimeException("已审批的订单不能取消");
        }
        
        String oldStatus = order.getApplicationStatus();
        order.setApplicationStatus("CANCELLED");
        order.setRejectReason(reason);
        order.setUpdateBy(currentUser);
        
        orderApplicationMapper.updateById(order);
        
        // 记录状态变更日志
        saveOrderStatusLog(order.getId(), order.getOrderNo(), oldStatus, 
            order.getApplicationStatus(), "取消订单：" + reason, currentUser);
        
        log.info("取消订单申请成功，订单ID：{}，订单编号：{}，原因：{}", 
            order.getId(), order.getOrderNo(), reason);
    }
    
    @Override
    public void approveOrder(OrderApprovalDto approvalDto, String currentUser) {
        OrderApplication order = orderApplicationMapper.selectById(approvalDto.getOrderId());
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 创建审批记录
        OrderApprovalRecord record = new OrderApprovalRecord();
        record.setOrderId(order.getId());
        record.setProcessInstanceId(order.getProcessInstanceId());
        record.setTaskId(approvalDto.getTaskId());
        record.setApproverId(Long.valueOf(approvalDto.getApproverId()));
        record.setApproverName(approvalDto.getApproverName());
        record.setApproverRole(approvalDto.getApproverRole());
        record.setApprovalStep(approvalDto.getApprovalStep());
        record.setApprovalResult(approvalDto.getApprovalResult());
        record.setApprovalComment(approvalDto.getApprovalComment());
        record.setApprovalTime(LocalDateTime.now());
        
        orderApprovalRecordMapper.insert(record);
        
        // 更新订单状态
        String oldStatus = order.getApplicationStatus();
        if ("APPROVED".equals(approvalDto.getApprovalResult())) {
            // 根据当前步骤决定下一步
            String nextStep = getNextApprovalStep(approvalDto.getApprovalStep());
            if (nextStep == null) {
                // 所有审批完成
                order.setApplicationStatus("APPROVED");
                order.setCurrentStep("审批完成");
                order.setCurrentApprover(null);
            } else {
                order.setCurrentStep(nextStep);
                order.setCurrentApprover(getNextApprover(nextStep));
            }
        } else {
            // 审批拒绝
            order.setApplicationStatus("REJECTED");
            order.setRejectReason(approvalDto.getApprovalComment());
            order.setRejectStep(approvalDto.getApprovalStep()); // 设置拒绝的步骤
            order.setCurrentStep("审批拒绝");
            order.setCurrentApprover(null);
        }
        
        order.setUpdateBy(currentUser);
        orderApplicationMapper.updateById(order);
        
        // 记录状态变更日志
        saveOrderStatusLog(order.getId(), order.getOrderNo(), oldStatus, 
            order.getApplicationStatus(), "审批：" + approvalDto.getApprovalResult(), currentUser);
        
        log.info("订单审批完成，订单ID：{}，订单编号：{}，审批结果：{}", 
            order.getId(), order.getOrderNo(), approvalDto.getApprovalResult());
    }
    
    @Override
    public OrderProcessDto getOrderProcess(Long orderId) {
        OrderApplication order = orderApplicationMapper.selectById(orderId);
        if (order == null) {
            return null;
        }
        
        OrderProcessDto dto = new OrderProcessDto();
        dto.setProcessInstanceId(order.getProcessInstanceId());
        dto.setProcessStatus(order.getApplicationStatus());
        dto.setCurrentStep(order.getCurrentStep());
        dto.setCurrentApprover(order.getCurrentApprover());
        
        return dto;
    }
    
    @Override
    public List<OrderProcessDto.ProcessStepDto> getOrderProcessSteps(String processInstanceId) {
        // 使用XML中的自定义查询方法
        QueryWrapper<OrderApprovalRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("process_instance_id", processInstanceId);
        List<OrderApprovalRecord> records = orderApprovalRecordMapper.selectList(queryWrapper);
        
        return records.stream().map(record -> {
            OrderProcessDto.ProcessStepDto stepDto = new OrderProcessDto.ProcessStepDto();
            stepDto.setTaskId(record.getTaskId());
            stepDto.setTaskName(record.getApprovalStep());
            stepDto.setAssignee(record.getApproverName());
            stepDto.setStatus("COMPLETED");
            stepDto.setComment(record.getApprovalComment());
            stepDto.setResult(record.getApprovalResult());
            return stepDto;
        }).collect(Collectors.toList());
    }
    
    /**
     * 根据客户名称查询订单
     */
    public List<OrderApplication> getOrdersByCustomerName(String customerName) {
        return orderApplicationMapper.selectByCustomerName(customerName);
    }
    
    /**
     * 查询指定审批人的待审批订单
     */
    public List<OrderApplication> getPendingOrdersByApprover(String approverName) {
        return orderApplicationMapper.selectPendingOrdersByApprover(approverName);
    }
    
    /**
     * 查询最近的订单
     */
    public List<OrderApplication> getRecentOrders(Integer limit) {
        return orderApplicationMapper.selectRecentOrders(limit);
    }
    
    /**
     * 根据审批人查询审批记录
     */
    public List<OrderApprovalRecord> getApprovalRecordsByApprover(String approverName) {
        return orderApprovalRecordMapper.selectByApprover(approverName);
    }
    
    /**
     * 查询订单状态变更历史
     */
    public List<OrderStatusLog> getOrderStatusHistory(Long orderId) {
        return orderStatusLogMapper.selectByOrderId(orderId);
    }
    
    @Override
    public Map<String, Object> getOrderStatistics(String currentUser) {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总订单数
        Long totalOrders = orderApplicationMapper.selectCount(null);
        statistics.put("totalOrders", totalOrders);
        
        // 使用自定义查询方法统计各状态订单数
        Long pendingOrders = orderApplicationMapper.countByStatus("PENDING");
        statistics.put("pendingOrders", pendingOrders);
        
        Long approvedOrders = orderApplicationMapper.countByStatus("APPROVED");
        statistics.put("approvedOrders", approvedOrders);
        
        Long rejectedOrders = orderApplicationMapper.countByStatus("REJECTED");
        statistics.put("rejectedOrders", rejectedOrders);
        
        Long cancelledOrders = orderApplicationMapper.countByStatus("CANCELLED");
        statistics.put("cancelledOrders", cancelledOrders);
        
        return statistics;
    }
    
    @Override
    public List<OrderApplication> getUserOrderApplications(String currentUser) {
        QueryWrapper<OrderApplication> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("create_by", currentUser);
        queryWrapper.orderByDesc("create_time");
        return orderApplicationMapper.selectList(queryWrapper);
    }
    
    @Override
    public List<OrderApplication> getPendingOrderApplications(String currentUser) {
        QueryWrapper<OrderApplication> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("current_approver", currentUser);
        queryWrapper.eq("application_status", "PENDING");
        queryWrapper.orderByDesc("create_time");
        return orderApplicationMapper.selectList(queryWrapper);
    }
    
    /**
     * 生成订单编号
     */
    private String generateOrderNo() {
        return "ORD" + System.currentTimeMillis();
    }
    
    /**
     * 保存订单状态变更日志
     */
    private void saveOrderStatusLog(Long orderId, String orderNo, String oldStatus, String newStatus, String reason, String operator) {
        OrderStatusLog log = new OrderStatusLog();
        log.setOrderId(orderId);
        log.setOrderNo(orderNo);
        log.setOldStatus(oldStatus);
        log.setNewStatus(newStatus);
        log.setChangeReason(reason);
        log.setOperatorId(1L); // 这里应该从当前用户信息中获取
        log.setOperatorName(operator);
        
        orderStatusLogMapper.insert(log);
    }
    
    /**
     * 获取下一个审批步骤
     */
    private String getNextApprovalStep(String currentStep) {
        Map<String, String> stepMap = new HashMap<>();
        stepMap.put("地区经理审批", "大区经理审批");
        stepMap.put("大区经理审批", "市场部审批");
        stepMap.put("市场部审批", "物流总监审批");
        stepMap.put("物流总监审批", "销售总监审批");
        stepMap.put("销售总监审批", "公司商务审批");
        stepMap.put("公司商务审批", null);
        
        return stepMap.get(currentStep);
    }
    
    /**
     * 获取下一个审批人
     */
    private String getNextApprover(String nextStep) {
        Map<String, String> approverMap = new HashMap<>();
        approverMap.put("大区经理审批", "王总监");
        approverMap.put("市场部审批", "赵经理");
        approverMap.put("物流总监审批", "陈总监");
        approverMap.put("销售总监审批", "刘总监");
        approverMap.put("公司商务审批", "周商务");
        
        return approverMap.get(nextStep);
    }
    
    @Override
    public void updateOrderStatus(Long orderId, String status, String reason) {
        OrderApplication order = orderApplicationMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        String oldStatus = order.getApplicationStatus();
        order.setApplicationStatus(status);
        order.setUpdateBy("system");
        
        if ("REJECTED".equals(status)) {
            order.setRejectReason(reason);
            order.setCurrentStep("审批拒绝");
            order.setCurrentApprover(null);
        } else if ("APPROVED".equals(status)) {
            order.setCurrentStep("审批完成");
            order.setCurrentApprover(null);
        }
        
        orderApplicationMapper.updateById(order);
        
        // 记录状态变更日志
        saveOrderStatusLog(order.getId(), order.getOrderNo(), oldStatus, 
            status, "系统自动更新状态", "system");
        
        log.info("订单状态更新成功，订单ID：{}，订单编号：{}，状态：{}", 
            order.getId(), order.getOrderNo(), status);
    }
    
    /**
     * 更新订单状态（包含拒绝步骤信息）
     */
    public void updateOrderStatusWithRejectStep(Long orderId, String status, String reason, String rejectStep) {
        OrderApplication order = orderApplicationMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        String oldStatus = order.getApplicationStatus();
        order.setApplicationStatus(status);
        order.setUpdateBy("system");
        
        if ("REJECTED".equals(status)) {
            order.setRejectReason(reason);
            order.setRejectStep(rejectStep);
            order.setCurrentStep("审批拒绝");
            order.setCurrentApprover(null);
        } else if ("APPROVED".equals(status)) {
            order.setCurrentStep("审批完成");
            order.setCurrentApprover(null);
        }
        
        orderApplicationMapper.updateById(order);
        
        // 记录状态变更日志
        saveOrderStatusLog(order.getId(), order.getOrderNo(), oldStatus, 
            status, "系统自动更新状态", "system");
        
        log.info("订单状态更新成功，订单ID：{}，订单编号：{}，状态：{}，拒绝步骤：{}", 
            order.getId(), order.getOrderNo(), status, rejectStep);
    }
    
    @Override
    public void updateOrderStep(Long orderId, String currentStep, String processInstanceId) {
        OrderApplication order = orderApplicationMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        String oldStep = order.getCurrentStep();
        order.setCurrentStep(currentStep);
        order.setProcessInstanceId(processInstanceId);
        order.setUpdateBy("system");
        
        orderApplicationMapper.updateById(order);
        
        // 记录状态变更日志
        saveOrderStatusLog(order.getId(), order.getOrderNo(), oldStep, 
            currentStep, "系统自动更新步骤", "system");
        
        log.info("订单步骤更新成功，订单ID：{}，订单编号：{}，当前步骤：{}", 
            order.getId(), order.getOrderNo(), currentStep);
    }
}